/*
 * Created on Dec 29, 2003
 */
package com.unash.asn;

/**
 * @author Ashwini Gokhale
 */
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

import com.unash.util.AsnUtil;
import com.unash.util.ByteArray;
import com.unash.util.Consts;

public class BerEncoder implements Consts{

	public static byte[] encodeInteger(AsnInteger obj){
		ByteArray value = ByteArray.binaryValue(obj.getValue());
		return value.getValue();
	}//EncodeInteger(int value)
	
	
	public static byte[] encodeBoolean(AsnBoolean obj){
		byte result[] = new byte[ONE];
		if(false == obj.isValue())
			result[0] = BER_FALSE;
		else 
			result[0] = BER_TRUE;
		return result;
	}//EncodeBoolean(boolean value)
	
	
	public static byte[] encodeBitString(AsnBitString obj){
		byte[] result = new byte[obj.getValue().length + ONE];
		result[ZERO] = (byte)obj.getUnusedBits();
		System.arraycopy(obj.getValue(),ZERO,result,ONE,obj.getValue().length);
		return result;
	}//encodeBitString(AsnBitString value)
	
	
	public static byte[] encodeOctetString(AsnOctetString obj){
		byte[] result = new byte[obj.getValue().length];
		System.arraycopy(obj.getValue(),ZERO,result,ZERO,obj.getValue().length);
		return result;	
	}//encodeOctetString(AsnOctetString value)
	
	
	public static byte[] encodeVisibleString(AsnVisibleString obj)
	throws UnsupportedEncodingException{
		byte[] result = obj.getBytes(); 
		return result;
	}//encodeVisibleString(AsnVisibleString value)
	
	public static byte[] encodeObjectIdentifier(AsnObjectIdentifier obj) {
		try {
			assert obj.getValue().length >= 1: "ObjectIdentifier should have at least one subidentifiers";
			
			int[] oidValue = obj.getValue();
			int noOfSubIdentifiers = oidValue.length;
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			//Encode first two integers as special case
			int firstSubId = oidValue[0];
			int secondSubId = noOfSubIdentifiers > 1? 
								oidValue[1]:0;
			/**
			 * First two subidentifiers are compressed in the first octet
			 * as per BER specifications.. It is assumed that first identifier will always have values 0, 1
			 * and second identifier will have values from 0-39 so both can be fitted in one octet
			 */
			int firstOctet = firstSubId * 40 + secondSubId;
			
			baos.write(AsnUtil.intToBerByteArray(firstOctet));
			
			for (int i = 2; i < noOfSubIdentifiers; i++) {
				byte[] encodedString = AsnUtil.intToBerByteArray(oidValue[i]);
				baos.write(encodedString);
			}
			return baos.toByteArray();
		}
		catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return new byte[0];

	}//encodeObjectIdentifier
	
}//BerEncoder